<template>
  <div class="p-l-d">
    <n-card>
      <div>
        <n-button
          style="margin-right: 5px"
          type="primary"
          dashed
          size="small"
          @click="openDialog"
        >
          <template #icon>
            <n-icon>
              <AddCircleOutline />
            </n-icon>
          </template>
          新增
        </n-button>
        <n-button type="primary" dashed size="small" @click="unfoldTree">
          <template #icon>
            <n-icon>
              <ReorderThree />
            </n-icon>
          </template>
          {{ defaultExpand ? "全部收起" : "全部展开" }}
        </n-button>
      </div>
      <n-tree
        style="margin-top: 1em"
        block-line
        :data="menuData"
        :default-selected-keys="defaultExpandedKeys"
        key-field="id"
        label-field="name"
        children-field="children"
        selectable
        :default-expand-all="defaultExpand"
        :node-props="nodeProps"
        :render-prefix="renderPrefix"
      />
    </n-card>
    <n-card title="菜单信息">
      <n-form
        label-placement="left"
        ref="formRef"
        :label-width="80"
        :model="formValue"
        :rules="rules"
        :size="size"
      >
        <n-form-item label="菜单名称" path="name">
          <n-input v-model:value="formValue.name" placeholder="请输入名称" />
        </n-form-item>
        <n-form-item label="菜单路由">
          <n-input v-model:value="formValue.router" placeholder="请输入路由" />
        </n-form-item>
        <n-form-item label="页面路径">
          <n-input v-model:value="formValue.pageUrl" placeholder="请输入路径" />
        </n-form-item>
        <n-form-item label="菜单类型" path="menuType">
          <n-select
            v-model:value="formValue.menuType"
            :options="menyTypeOptions"
          />
        </n-form-item>
        <n-form-item label="排序">
          <n-input-number
            style="width: 100%"
            v-model:value="formValue.sort"
            clearable
            placeholder="数字越大，排序越前"
          />
        </n-form-item>
        <n-form-item label="上级菜单">
          <n-tree-select
            placeholder="上级菜单"
            :options="menuTreeList"
            :value="formValue.parentID"
            @update:value="handleUpdateValue"
            key-field="id"
            label-field="name"
            children-field="children"
            :clearable="true"
            :default-expand-all="true"
          />
        </n-form-item>
        <n-form-item label="是否可用">
          <n-switch v-model:value="formValue.enable" size="medium">
            <template #checked> 可用 </template>
            <template #unchecked>禁用 </template>
            <template #checked-icon>
              <n-icon :component="CheckmarkDoneCircleSharp" />
            </template>
            <template #unchecked-icon>
              <n-icon :component="CloseCircleOutline" />
            </template>
          </n-switch>
        </n-form-item>
        <n-form-item label="菜单图标" path="previewFileList">
          <n-upload
            v-model:file-list="formValue.previewFileList"
            v-model:value="formValue.previewFileList"
            accept="image/png, image/jpeg"
            list-type="image-card"
            @preview="handlePreview"
            :max="1"
            :default-upload="false"
            :show-file-list="true"
            ref="uploadRef"
            :on-before-upload="handleBeforeRead"
            file-list-style="width:40px;height:40px;"
            trigger-style="width:40px;height:40px;"
            :show-preview-button="false"
            width="50px;"
          >
            <n-icon
              size="20"
              v-if="formValue.menuIcon != '' && formValue.menuIcon != null"
            >
              <img
                :src="formValue.menuIcon"
                style="width: 100%; height: 100%"
                alt=""
              />
            </n-icon>
          </n-upload>
        </n-form-item>
        <n-form-item style="justify-items: end">
          <n-button size="small" type="primary" @click="handleValidateClick"
            >立即更新</n-button
          >
        </n-form-item>
      </n-form>
    </n-card>

    <my-dialog
      :showModal="showModal"
      @closeModal="closeModal"
      @getMenuListPage="getMenuListPage"
      ref="myDialogRef"
    ></my-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, h, onMounted } from "vue";
import {
  ReorderThree,
  AddCircleOutline,
  CheckmarkDoneCircleSharp,
  CloseCircleOutline,
} from "@vicons/ionicons5";
import { NButton, NIcon } from "naive-ui";
import myDialog from "./dialog.vue";
import {
  getMenuList,
  getMenuById,
  updateMenu,
  getMenuTree,
} from "@/api/menu.ts";
import { searchMenuRequest, updateMenuRequest } from "@/models/menuModel.ts";

const menuData = ref();
const defaultExpandedKeys = ref<Array<String>>([]);
const defaultExpand = ref(true);
const showModal = ref(false);
const myDialogRef = ref<any>(null);
const queryInfo = ref<searchMenuRequest>({
  pageIndex: 1,
  pageSize: 10,
  menuName: null,
  menuType: null,
});
const formRef: any = ref(null);
const formValue = ref<updateMenuRequest>({
  parentID: null,
  name: "",
  router: "",
  pageUrl: "",
  menuType: 2,
  menuIcon: "",
  sort: 0,
  enable: true,
});
const rules = {
  name: {
    required: true,
    trigger: ["blur", "input"],
    message: "请给菜单一个名字",
  },
  menuType: {
    type: "number",
    required: true,
    trigger: ["blur", "change"],
    message: "菜单还没有类型",
  },
};
const menyTypeOptions = ref([
  {
    value: 1,
    label: "目录",
  },
  {
    value: 2,
    label: "菜单",
  },
  {
    value: 3,
    label: "按钮",
  },
]);
const menuTreeList = ref();

onMounted(() => {
  getMenuListPage();
});
const getMenuListPage = () => {
  getMenuList(queryInfo.value).then((res) => {
    menuData.value = [];
    menuData.value = res.data;
    defaultExpandedKeys.value.push(menuData.value[0].id);
    getMenuInfoById(menuData.value[0].id);
    getMenuTree().then((res) => {
      menuTreeList.value = res.data;
    });
  });
};
const unfoldTree = () => {
  defaultExpand.value = !defaultExpand.value;
};
const nodeProps = (val) => {
  return {
    onClick() {
      getMenuInfoById(val.option.id);
    },
  };
};
const getMenuInfoById = (id) => {
  getMenuById({ id: id }).then((res) => {
    formValue.value.name = res.data.name;
    formValue.value.parentID = res.data.parentID;
    formValue.value.router = res.data.router;
    formValue.value.pageUrl = res.data.pageUrl;
    formValue.value.menuType = res.data.menuType;
    formValue.value.menuIcon = res.data.menuIcon;
    formValue.value.sort = res.data.sort;
    formValue.value.enable = res.data.enable;
    formValue.value.id = res.data.id;
    menuTreeList.value = menuTreeList.value.map((node) =>
      menuTreeEach(node, id)
    );
  });
};
const menuTreeEach = (node, id) => {
  // 创建一个新的节点对象，默认 disabled 为 false
  const newNode = { ...node, disabled: false };
  // 检查当前节点的 id
  if (node.id === id) {
    // 设置符合条件的节点为 disabled: true
    newNode.disabled = true;
  }

  // 递归遍历子节点
  if (node.children) {
    newNode.children = node.children.map((child) => menuTreeEach(child, id)); // 递归处理子节点
  }

  return newNode; // 返回处理后的节点
};

const getMenuIcon = (url) => {
  // 这里可以是一个图标组件或者图片
  return h("img", {
    src: url,
    style: "width: 100%; height: auto;",
  });
};
const renderPrefix = (value) => {
  return h(NIcon, null, { default: () => h(getMenuIcon(value.option.icon)) });
};
const openDialog = () => {
  showModal.value = true;
  myDialogRef.value?.init();
};
const closeModal = () => {
  showModal.value = false;
};
const handleBeforeRead = async ({ file }: any) => {
  // 创建 FileReader 对象
  const reader: any = new FileReader();
  console.log(file);
  reader.onload = () => {
    const blobUrl = reader.result as string;
    // 将读取结果转换为 Base64 格式并进行处理
    const base64Data = reader.result.split(",")[1]; // 获取 base64 数据部分
    // 进行后续处理，比如发送到服务器等
    formValue.value.menuIcon = "data:image/png;base64," + base64Data;
    file.file.url = blobUrl;
  };

  // 读取文件并转换为 Data URL
  reader.readAsDataURL(file.file);
  // 你可以决定是否继续上传，返回true则继续，返回false则取消上传
  return false;
};
const handleValidateClick = (e) => {
  e.preventDefault();
  formRef.value?.validate((errors) => {
    if (!errors) {
      updateMenu(formValue.value).then((res) => {
        if (res.code == 200) {
          window.$message.success(res.message);
          getMenuListPage();
        }else{
          window.$message.error(res.message);
        }
      });
    } else {
      console.log(formValue.value);
      window.$message.error("表单验证错误");
    }
  });
};
const handleUpdateValue = (value) => {
  formValue.value.parentID = value;
};
</script>

<style lang="scss" scoped>
.p-l-d {
  display: grid;
  grid-template-columns: 30% calc(70% - 10px);
  gap: 10px;
  align-items: start;
}
</style>
